import classNames from 'classnames'
import React, { useEffect, useRef, useState, useMemo } from 'react'
import type { NotificationArgsProps } from 'antd'
import styles from './home.module.scss'
import { Flex, Segmented, message, Empty, Drawer, Space, Button, notification } from 'antd'
import { createFromIconfontCN, SmileOutlined } from '@ant-design/icons'
import DefaultType from './components/question-list'
import { getQuestion, getSource, reservation } from '@/api/question'
import { ErrorTip } from '@/utils/errorTip'
import { useSelector } from 'react-redux'
import { GotoPage } from '@/utils/gotoPage'
import { useLocation } from 'react-router-dom'
import { socketUrl } from '@/utils/config'

import Calender from '@/components/calendar/calendar'
import { BaseResponse } from '@/type/api'

const IconFont = createFromIconfontCN({
  scriptUrl: ['//at.alicdn.com/t/c/font_3515098_lsx5wphvzwk.js']
})

type NotificationPlacement = NotificationArgsProps['placement']

const Context = React.createContext({ name: 'Default' })

const Home: React.FC = () => {
  /**
   * 变量集合
   */
  const [sourceList, setSourceList] = useState<SourceTyp[]>([])
  const [sourceSelectIndex, setSourceIndex] = useState(0)
  const left = useRef(null)
  const [isHovered, setIsHovered] = useState(false)
  const [messageApi, contextHolder] = message.useMessage()
  // const [QuestionTypeComponent, setTypeComponent] = useState<React.ComponentType<QuestionType>>()
  const [questionlist, setQuestionList] = useState<QuestionType[]>([])
  const [type, setType] = useState('single')
  const [typeIndex, setTypeIndex] = useState<string | number>(1)
  // let isLoading = false // 是否在加载数据
  const [isLoading, setIsLoading] = useState(false)
  const [sourcePage, setSourcePage] = useState(1)
  const [questionPage, setQuestionPage] = useState(1)
  const { token, userInfo } = useSelector((state: RootState) => state.handleUser)
  const gotoPage = new GotoPage()
  const routeLocation = useLocation()
  const [open, setOpen] = useState(false)
  const [examDate, setSExamDate] = useState(`${new Date().getFullYear()}-${new Date().getMonth() + 1}-${new Date().getDate()}`)

  // 通知框相关
  const [notificAtionapi, notificationContext] = notification.useNotification()
  const openNotification = (placement: NotificationPlacement) => {
    notificAtionapi.info({
      message: `恭喜, ${userInfo.name}!`,
      description: <Context.Consumer>{() => `考试预约成功，考试将在 ${examDate}进行`}</Context.Consumer>,
      placement,
      icon: <SmileOutlined style={{ color: '#108ee9' }} />
    })
  }
  const contextValue = useMemo(() => ({ name: userInfo.name }), [])

  /**
   * 获取题源 以及 消息
   */
  const GetSource = async () => {
    const res = await getSource({ page: sourcePage })
    if (ErrorTip(res)) return messageApi.open({ type: 'error', content: '错误：' + res.message })
    setSourceList([...sourceList, ...res.data.data])
  }

  useEffect(() => {
    GetSource()
  }, [])
  /**
   * 选择题源
   */
  const selectSource = (index: number) => {
    setSourceIndex(index)
  }

  /**
   * 鼠标悬停 滚动条展示
   */
  const handleHover = () => {
    setIsHovered(true)
  }
  const handleLeave = () => {
    setIsHovered(false)
  }

  /**
   * 滚动
   */
  interface scrollType {
    target: {
      scrollHeight: number
      scrollTop: number
      clientHeight: number
    }
  }
  const sourceScroll = async (e: React.UIEvent<HTMLElement, UIEvent>) => {
    const event = e as unknown as scrollType

    if (isLoading) {
      return
    }
    if (event.target.scrollHeight - event.target.scrollTop <= event.target.clientHeight + 5) {
      console.log('开始加载了')
      setIsLoading(false)
      setSourcePage(prevPage => prevPage + 1)
      await GetSource()
      setIsLoading(true)
    }
  }

  /**
   * 选择题型
   */

  // 处理多选题选项
  const handleMultipleOptions = async (list: BaseResponse) => {
    const m_list = await list.data.data.map((item: QuestionType) => {
      const updateOption = item.options.map(option => {
        return {
          label: option.content,
          value: option.option
        }
      })
      return {
        ...item,
        options: updateOption
      }
    })
    return m_list
  }
  const selectType = async (e: string | number) => {
    setQuestionPage(1)
    let index = e
    if (typeof e === 'string') {
      index = parseInt(e)
    }
    const typelist = ['single', 'multiple', 'judgment', 'QA']
    setType(typelist[(index as number) - 1])
    setTypeIndex(index)
    setQuestionList([])

    const listRes = await getQuestion({ page: 1, type: index, sourceid: sourceSelectIndex + 1 })

    if (listRes.code < 200 || listRes.code >= 399) {
      return messageApi.open({ content: '错误：' + listRes.message })
    }
    if (index === 2) {
      if (!listRes.data.data) return
      const m_list = handleMultipleOptions(listRes)
      setQuestionList([...(await m_list)])
    } else setQuestionList([...listRes.data.data])
  }
  useEffect(() => {
    selectType(typeIndex)
    setQuestionPage(1)
  }, [sourceSelectIndex])

  /**
   * 加载更多题
   */
  const loadingMoreQuestion = async (e: React.UIEvent<HTMLElement, UIEvent>) => {
    const event = e as unknown as scrollType

    if (isLoading) return
    if (event.target.scrollHeight - event.target.scrollTop <= event.target.clientHeight + 5) {
      console.log('加载题咯')
      setIsLoading(true)
      setQuestionPage(prevPage => prevPage + 1)
      const res = await getQuestion({ page: questionPage, type: typeIndex, sourceid: sourceSelectIndex + 1 })
      if (ErrorTip(res)) return messageApi.open({ type: 'error', content: '错误：' + res.message })
      if (typeIndex === 2) {
        if (!res.data.data) return
        const m_list = handleMultipleOptions(res)
        setQuestionList([...questionlist, ...(await m_list)])
      } else setQuestionList([...questionlist, ...res.data.data])
    }
    setIsLoading(false)
  }

  /**
   * 预约 and 模拟考试
   */
  const exam = () => {
    if (!token) {
      return messageApi.error('请先登录呦')
    }
    setOpen(true)
  }
  const simulation = () => {
    // messageApi.warning('开发中')
    if (!token) {
      return messageApi.error('请先登录呦')
    }
    gotoPage.gotoExam({ from: routeLocation.pathname.substring(1) }, 1)
  }
  // 关闭抽屉
  const onClose = () => {
    setOpen(false)
  }

  /**
   * 日历子组件传递过来的值
   */
  const selectedDate = (date: string) => {
    setSExamDate(date)
  }
  // ok按钮
  const onDateOk = async () => {
    // const socket = new WebSocket('ws://127.0.0.1:8866')
    // socketUrl
    const socket = new WebSocket(socketUrl)

    socket.addEventListener('open', () => {
      console.log('socket连接打开')
      socket.send(
        JSON.stringify({
          event: 'reservation', // 可以根据实际情况定义不同的消息类型
          data: '考试预约'
        })
      )
    })

    // 连接关闭时触发
    socket.addEventListener('close', () => {
      console.log('WebSocket 连接已关闭')
    })

    const res = await reservation({ endtime: examDate }, userInfo.id)
    if (ErrorTip(res)) return messageApi.open({ type: 'error', content: '错误：' + res.message })
    messageApi.success('预约考试成功')
    openNotification('topRight')
    setSExamDate(`${new Date().getFullYear()}-${new Date().getMonth() + 1}-${new Date().getDate()}`)
    onClose()
  }

  return (
    <>
      <Context.Provider value={contextValue}>{notificationContext}</Context.Provider>
      {contextHolder}
      <Drawer
        title={`选择日期`}
        placement="top"
        onClose={onClose}
        open={open}
        height={520}
        extra={
          <Space>
            <Button onClick={onClose}>Cancel</Button>
            <Button type="primary" onClick={onDateOk}>
              OK
            </Button>
          </Space>
        }
      >
        <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
          <Calender onGetDate={selectedDate} />
        </div>
      </Drawer>
      <div className={classNames(styles.box_home)}>
        <Flex vertical={false} style={{ height: '95%' }}>
          {/* 左边 */}
          <div
            className={classNames(styles.left, { [styles.hovered]: isHovered })}
            onScroll={e => sourceScroll(e)}
            ref={left}
            onMouseOver={handleHover}
            onMouseLeave={handleLeave}
          >
            <div className={classNames(styles.left_list)}>
              <div className={classNames(styles.header)}>题源</div>
              {sourceList.map((item, index) => (
                <div
                  onClick={() => selectSource(index)}
                  className={classNames(styles.source_item, { [styles.source_select]: sourceSelectIndex == index })}
                  key={index}
                >
                  {item.source}
                  {sourceSelectIndex === index && <div className={classNames(styles.triangle)}></div>}

                  <div className={classNames(styles.mark)}></div>
                </div>
              ))}
              {sourceList.length < 1 && <Empty />}
            </div>
          </div>
          {/* 中间 */}
          <div className={classNames(styles.middle)}>
            <div
              className={classNames(styles.box_content, { [styles.hovered]: isHovered })}
              onMouseOver={handleHover}
              onMouseLeave={handleLeave}
              onScroll={e => loadingMoreQuestion(e)}
            >
              <Segmented
                size={'large'}
                options={[
                  // Single multiple judgment  QA
                  { label: '单选题', value: '1', icon: <IconFont type="icon-danxuanti" /> },
                  { label: '多选题 ', value: '2', icon: <IconFont type="icon-duoxuanti" /> },
                  { label: '判断题', value: '3', icon: <IconFont type="icon-panduanti" /> },
                  { label: '简答题', value: '4', icon: <IconFont type="icon-jiandati" /> }
                ]}
                onChange={e => selectType(e)}
              />
              <div className={classNames(styles.content)}>
                <DefaultType questionlist={questionlist} type={type} />
                {/* {QuestionTypeComponent ? <QuestionTypeComponent questionlist={questionlist} /> : <DefaultType questionlist={questionlist} />} */}
              </div>
            </div>
          </div>
          {/* 右边 */}
          <div className={classNames(styles.right)}>
            <Flex vertical={true} style={{ height: '100%' }}>
              <div className={classNames(styles.box_btn_exam)}>
                <div className={classNames(styles.btn_exam, styles.btn)} onClick={() => exam()}>
                  <div className={classNames(styles.mark)}></div>
                  预约考试
                </div>

                <div className={classNames(styles.btn_simulation, styles.btn)} onClick={() => simulation()}>
                  <div className={classNames(styles.mark)}></div>
                  模拟考试
                </div>
              </div>
              <div className={classNames(styles.announcement)}>
                <div className={classNames(styles.header)}>公告</div>
              </div>
            </Flex>
          </div>
        </Flex>
      </div>
    </>
  )
}

export default Home
